#pragma once
#ifndef JoStudio_Vector_H
#define JoStudio_Vector_H

class JVector
{
public:
	//C
	JVector():x(0),y(0),z(0){}
	JVector(DOUBLE X,DOUBLE Y,DOUBLE Z):x(X),y(Y),z(Z){}
	JVector(const JVector& Vec){x=Vec.x;y=Vec.y;z=Vec.z;}
	JVector(const D3DXVECTOR3& Vec){x=Vec.x;y=Vec.y;z=Vec.z;}

	//O
	void Set(DOUBLE X,DOUBLE Y,DOUBLE Z){x=X;y=Y;z=Z;}

	void Add(const JVector&rv){x+=rv.x;y+=rv.y;z+=rv.z;}								//This=This+rv
	void Add(const JVector&lv,const JVector&rv){x=lv.x+rv.x;y=lv.y+rv.y;z=lv.z+rv.z;}	//This=lv+rv
	void Sub(const JVector&rv){x=x-rv.x;y=y-rv.y;z=z-rv.z;}								//This=This-rv
	void Sub(const JVector&lv,const JVector&rv){x=lv.x-rv.x;y=lv.y-rv.y;z=lv.z-rv.z;}	//This=lv-rv

	DOUBLE Dot(const JVector&rv){return x*rv.x+y*rv.y+z*rv.z;}							//r=This dot rv
	void Cross(const JVector lv,const JVector rv){x=lv.y*rv.z-lv.z*rv.y;y=lv.z*rv.x-lv.x*rv.z;z=lv.x*rv.y-lv.y*rv.x;}	//This=lv cross rv
	void Multiplication(const JVector&rv){x*=rv.x;y*=rv.y;z*=rv.z;}									//This=This*rv (for x,y,z independence)
	void Multiplication(const JVector&lv,const JVector&rv){x=lv.x*rv.x;y=lv.y*rv.y;z=lv.z*rv.z;}	//This=lv*rv  (for x,y,z independence)
	void Division(const JVector&rv){x/=rv.x;y/=rv.y;z/=rv.z;}										//This=This/rv  (for x,y,z independence)
	void Division(const JVector&lv,const JVector&rv){x=lv.x/rv.x;y=lv.y/rv.y;z=lv.z/rv.z;}			//This=lv/rv  (for x,y,z independence)
	void Division(DOUBLE d){x/=d;y/=d;z/=d;}														//This=This/d  (for x,y,z independence)

	DOUBLE Length(){return sqrt(x*x+y*y+z*z);}														//r=|This|
	DOUBLE Length2(){return x*x+y*y+z*z;}															//r=|This|^2
	void Normalize(){DOUBLE l=this->Length();x/=l;y/=l;z/=l;}										//This/=|This|

	void Scale(DOUBLE s){x*=s;y*=s;z*=s;}															//This*=s
	void Scaled(const JVector&lv,DOUBLE s){x=lv.x*s;y=lv.y*s;z=lv.z*s;}								//This=lv*s
	void AddScaled(const JVector&lv,const JVector&rv,DOUBLE s){x=lv.x+rv.x*s;y=lv.y+rv.y*s;z=lv.z+rv.z*s;}	//This=lv+rv*s

	DOUBLE x,y,z;
};
#endif